package com.autumn.platform.web.resulthandler.context;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;

import com.autumn.platform.core.logger.Logs;
import com.autumn.platform.web.WebHolder;

public class HandlerMethodContextHolder {

    private static final String METHOD_KEY = HandlerMethodContextHolder.class.getName() + ".HandlerMethod";

    private static final String RESULT_KEY = HandlerMethodContextHolder.class.getName() + ".HandlerMethodContext";

    private static HandlerMappingIntrospector introspector;

    public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        try {
            introspector = applicationContext.getBean(HandlerMappingIntrospector.class);
        } catch (Exception e) {
            Logs.warn("not found HandlerMappingIntrospector instance");
        }
    }

    public static HandlerMethod getHandlerMethod() {
        Object method = WebHolder.getRequestAttribute(METHOD_KEY);
        if (method instanceof HandlerMethod) {
            return (HandlerMethod) method;
        } else if (null == WebHolder.getRequestAttribute(METHOD_KEY + ".FLAG")) {
            WebHolder.setRequestAttribute(METHOD_KEY + ".FLAG", new Object());
            try {
                HttpServletRequest request = WebHolder.getRequest();
                if (null != request && null != introspector) {
                    for (HandlerMapping mapping : introspector.getHandlerMappings()) {
                        HandlerExecutionChain chain = mapping.getHandler(request);
                        if (null != chain && chain.getHandler() instanceof HandlerMethod) {
                            HandlerMethod handlerMethod = (HandlerMethod) chain.getHandler();
                            WebHolder.setRequestAttribute(METHOD_KEY, handlerMethod);
                            return handlerMethod;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static HandlerMethodContext getHandlerMethodContext() {
        return (HandlerMethodContext) WebHolder.getRequestAttribute(RESULT_KEY);
    }

    public static void setHandlerMethodContext(HandlerMethodContext handlerMethodContext) {
        WebHolder.setRequestAttribute(RESULT_KEY, handlerMethodContext);
    }
}
